﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection.Metadata.Ecma335;
using System.Text;
using System.Threading.Tasks;
using 垃圾小游戏.class3;
using 垃圾小游戏.class4;
using 垃圾小游戏.class5;

namespace 垃圾小游戏.class6
{
    /// <summary>
    /// 蛇的移动方向
    /// </summary>
    enum E_MoveDir
    {
        up,
        down, 
        left,
        right
    }
    class Snake : IDraw
    {
        SnakeBody[] bodys;//身体个数
        int nowNum;//记录蛇的长度
        E_MoveDir dir;//当前移动方向
        public Snake(int x,int y)
        {
            //直接申明200个空间
            bodys = new SnakeBody[200];

            bodys[0] = new SnakeBody(E_SnakeBody_Type.Head,x,y);
            nowNum = 1;
            dir = E_MoveDir.right;//默认出场向右
        }
        public void Draw()
        {
            //绘制身体
            for (int i = 0; i < nowNum; i++)
            {
                bodys[i].Draw();//一节一节地生成
            }
        }
        #region     lesson7 蛇的移动
        public void Move()
        {
            //移动前擦除最后一个位置
            SnakeBody lastbody = bodys[nowNum - 1];
            Console.SetCursorPosition(lastbody.pos.x,lastbody.pos.y);
            Console.Write("  ");

            //在蛇头移动前从蛇尾开始 不停的让后一个位置 等于前一个位置
            for (int i = nowNum - 1;i > 0;i--)
            {
                bodys[i].pos = bodys[i - 1].pos;//蛇身的位置等于上一个蛇身的位置
            }

            //改变方向就是改变蛇头的位置
            switch(dir)
            {
                case E_MoveDir.up:
                    --bodys[0].pos.y;
                    break;
                case E_MoveDir.down:
                    ++bodys[0].pos.y;
                    break;
                case E_MoveDir.left:
                    bodys[0].pos.x -= 2;
                    break;
                case E_MoveDir.right:
                    bodys[0].pos.x += 2;
                    break;
            }
        }
        #endregion
        #region     lesson8 改变方向
        public void ChangeDir(E_MoveDir dir)
        {
            //只有头部的时候 可以直接左转右 右转左 上转下 下转上
            //有身体时 这种情况就不能直接转
            if(dir == this.dir || nowNum > 1&&
                (this.dir == E_MoveDir.left && dir == E_MoveDir.right ||
                 this.dir == E_MoveDir.right && dir == E_MoveDir.left ||
                 this.dir == E_MoveDir.up && dir == E_MoveDir.down ||
                 this.dir == E_MoveDir.down && dir == E_MoveDir.up))
            {
                return;
            }
            //只要没有return 就纪录外面传入的方向 之后就会按照这个方向去移动
            this.dir = dir;
        }
        #endregion

        #region     lesson9   碰撞身体结束逻辑  
        //检测蛇头是否撞墙，需要用到地图里的信息
        public bool CheckEnd(Map map)
        {
            //是否和墙体位置重合
            for(int i = 0;i < map.walls.Length;i++)//遍历墙的位置 
            {
                if (bodys[0].pos == map.walls[i].pos)
                {
                    return true;
                }
            }
            //是否和身体重合
            for(int i = 1; i < nowNum;i++)//0是头，所以从1开始
            {
                if (bodys[0].pos == bodys[i].pos)
                {
                    return true;
                }
            }
            return false;
        }
        #endregion

        #region     lesson10   吃食物相关
        /// <summary>
        /// 判断是否与蛇重合
        /// </summary>
        /// <param name="p"></param>
        /// <returns></returns>
        public bool CheckSamPos(Position p)
        {
            for (int i = 0;i < nowNum;i++)
            {
                if (bodys[i].pos == p)
                {
                    return true;
                }
            }
            return false;
        }

        //检查是否吃到了食物
        public void CheckEatFood(Food food)
        {
            if (bodys[0].pos == food.pos)
            {
                //吃到了就应该让食物位置再次随机 增加蛇身体的长度
                food.RandomPos(this);//this指的是snake
                //长身体
                AddBody();
            }
        }
        #endregion

        #region     lesson11   长身体相关
        private void AddBody()
        {
            SnakeBody frontBody = bodys[nowNum - 1];//索引减1就是长度
            //先长 
            bodys[nowNum] = new SnakeBody(E_SnakeBody_Type.Body, frontBody.pos.x, frontBody.pos.y);
            //再加长度
            ++nowNum;
        }
        #endregion 
    }
}
